package com.deram.ctin.serv.main.service.impl;

import com.deram.ctin.common.utils.ArrayHandleUtils;
import com.deram.ctin.serv.business.api.BusinessShareholderApi;
import com.deram.ctin.serv.enter.api.EnterInfoApi;
import com.deram.ctin.serv.enter.api.EnterMainUserApi;
import com.deram.ctin.serv.enter.api.EnterPersonApi;
import com.deram.ctin.serv.enter.entity.EnterInfo;
import com.deram.ctin.serv.enter.entity.EnterPerson;
import com.deram.ctin.serv.enter.filter.EnterInfoFilter;
import com.deram.ctin.serv.enter.filter.EnterPersonFilter;
import com.deram.ctin.serv.main.consts.EnterRelationConsts;
import com.deram.ctin.serv.main.service.EnterRelationService;
import com.deram.ctin.serv.main.vo.EnterRelationVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * @author zhangcm
 * @version 1.0, 2017/9/28
 */
@Service
public class EnterRelationServiceImpl implements EnterRelationService {

    @Autowired
    private EnterInfoApi enterInfoApi;

    @Autowired
    private EnterPersonApi enterPersonApi;

    @Override
    public EnterRelationVo findRelation(Long enterId, Integer level) {
        EnterInfo enterInfo = enterInfoApi.findById(enterId);
        EnterRelationVo relation = parseCompany(enterInfo, null, 1);
        fillChild(relation, level);
        return relation;
    }

    private void fillChild(EnterRelationVo relation, Integer maxLevel) {
        if(relation.getLevel() > maxLevel) {
            return;
        }
        switch (relation.getType()){
            case EnterRelationConsts.TYPE_COMPANY: fillCompanyChild(relation); break;
            case EnterRelationConsts.TYPE_PERSON: fillPersonChild(relation); break;
        }
        for (EnterRelationVo obj : relation.getChildList()) {
            fillChild(obj, maxLevel);
        }
    }

    private void fillCompanyChild(EnterRelationVo relation){
        EnterInfoFilter enterInfoFilter = new EnterInfoFilter();
        enterInfoFilter.setFatherId(relation.getId());
        List<EnterInfo> enterInfoList = enterInfoApi.list(enterInfoFilter);
        for (EnterInfo enterInfo : enterInfoList) {
            EnterRelationVo obj = parseCompany(enterInfo, EnterRelationConsts.RELATION_CHILD_COMPANY, relation.getLevel() + 1);
            relation.getChildList().add(obj);
        }
        EnterPersonFilter personFilter = new EnterPersonFilter();
        personFilter.setEnterId(relation.getId());
        List<EnterPerson> enterPersonList = enterPersonApi.list(personFilter);
        for (EnterPerson enterPerson : enterPersonList) {
            EnterRelationVo obj = parsePerson(enterPerson, enterPerson.getRelationshipName(), relation.getLevel() + 1);
            relation.getChildList().add(obj);
        }
    }

    private void fillPersonChild(EnterRelationVo relation){
        if(StringUtils.isEmpty(relation.getCode())){
            return;
        }
        EnterPersonFilter personFilter = new EnterPersonFilter();
        personFilter.setCode(relation.getCode());
        List<EnterPerson> enterPersonList = enterPersonApi.list(personFilter);
        List<Long> enterInfoIdList = ArrayHandleUtils.readAttrList(enterPersonList, "enterId");

        EnterInfoFilter enterInfoFilter = new EnterInfoFilter();
        enterInfoFilter.setIdList(enterInfoIdList);
        List<EnterInfo> enterInfoList = enterInfoApi.list(enterInfoFilter);
        Map<Long, EnterInfo> enterInfoMap = ArrayHandleUtils.parseMap(enterInfoList, "id");
        for (EnterPerson enterPerson : enterPersonList) {
            EnterInfo enterInfo = enterInfoMap.get(enterPerson.getEnterId());
            EnterRelationVo obj = parseCompany(enterInfo, enterPerson.getRelationshipName(), relation.getLevel() + 1);
            relation.getChildList().add(obj);
        }
    }

    private EnterRelationVo parseCompany(EnterInfo enterInfo, String relation, Integer level){
        EnterRelationVo obj = new EnterRelationVo();
        obj.setId(enterInfo.getId());
        obj.setName(enterInfo.getName());
        obj.setType(EnterRelationConsts.TYPE_COMPANY);
        obj.setRelation(relation);
        obj.setLevel(level);
        return obj;
    }

    private EnterRelationVo parsePerson(EnterPerson enterPerson, String relation, Integer level){
        EnterRelationVo obj = new EnterRelationVo();
        obj.setId(enterPerson.getId());
        obj.setCode(enterPerson.getCode());
        obj.setName(enterPerson.getName());
        obj.setType(EnterRelationConsts.TYPE_PERSON);
        obj.setRelation(relation);
        obj.setLevel(level);
        return obj;
    }
}
